L07 Layers

Data Visualization (STAT 302)

Author

DAVIS JOHNSON

Overview

The goal of this lab is to explore more plots in ggplot2 and continue to leverage the use of various layers to build complex and well annotated plots.

Load Datasets and Package(s)

We’ll be using the tech_stocks.rda dataset which is already in the /data subdirectory in our data_vis_labs project.

We have a new dataset, NU_admission_data.csv, which will need to be downloaded and added to our /data subdirectory.

We will also be using the mpg dataset which comes packaged with ggplot2 — use ?ggplot2::mpg to access its codebook.

Code
# load package(s)

library(tidyverse)
library(patchwork)
library(scales)
library(janitor)

# load datasets
load("data/tech_stocks.rda")

# load NU admissions data
admin_data <- read.csv("data/NU_admission_data.csv") %>%
  clean_names()

Exercise 1

Using mpg and the class_dat dataset created below, recreate the following graphic as precisely as possible in two different ways.

Hints:

  • Transparency is 0.6
  • Horizontal spread is 0.1
  • Larger points are 5
  • Larger points are “red”
Code
# additional dataset for plot
class_dat <- mpg %>%
  group_by(class) %>%
  summarise(
    n = n(),
    mean_hwy = mean(hwy),
    label = str_c("n = ", n, sep = "")
  )

Plot 1 – using mean_hwy

Solution
Code
ggplot(mpg, aes(class, hwy)) +
  geom_jitter(width = 0.1) +
  geom_point(
    data = class_dat, 
    aes(y = mean_hwy),
    size = 5, 
    color = "red", 
    alpha = 0.6) +
  geom_text(
    data = class_dat, 
    aes(x = class, y = 10, label = label), 
    ) +
  theme_minimal() +
  labs(
      x = "Vehicle Class"
    , y = "Highway miles per gallon"
  )

Plot 2 – not using mean_hwy

Solution
Code
ggplot(mpg, aes(class, hwy)) +
  geom_jitter(width = 0.1) +
  stat_summary(
    fun = mean, 
    geom = "point", 
    size = 5, 
    color = "red", 
    alpha = 0.6
  ) +
  geom_text(
    data = class_dat, 
    aes(x = class, y = 10, label = label), 
    ) + 
  theme_minimal() +
  labs(
    x = "Vehicle Class", 
    y = "Highway miles per gallon"
  )

Exercise 2

Using the perc_increase dataset derived from the tech_stocks dataset, recreate the following graphic as precisely as possible.

Hints:

  • Hex color code #56B4E9
  • Justification of 1.1
  • Size is 5
Code
# percentage increase data
perc_increase <- tech_stocks %>%
  arrange(desc(date)) %>%
  distinct(company, .keep_all = TRUE) %>%
  mutate(
    perc = 100 * (price - index_price) / index_price,
    label = str_c(round(perc), "%", sep = ""),
    company = fct_reorder(factor(company), perc)
  )
Solution
Code
ggplot(perc_increase, aes(perc, company)) +
  geom_col(fill = "#56B4E9") + 
  geom_text(
    aes(label = label), 
    size = 5, 
    hjust = 1.1, 
    color = "white") +
  theme_minimal() +
  labs(
      x = NULL
    , y = NULL
  )

Exercise 3

Using NU_admission_data.csv create two separate plots derived from the single plot depicted in undergraduate-admissions-statistics.pdf — this visual and data has been collected from https://www.adminplan.northwestern.edu/ir/data-book/. They overlaid two plots on one another by using dual y-axes.

Create two separate plots that display the same information instead of trying to put it all in one single plot — stack them using patchwork or cowplot.

There is one major error they make with the bars in their graphic. Explain what it is.

Solution

They stacked the bar charts incorrectly. The three components of each bar are just stacked on top of one another. For example, the 2001 bar has a total of 13,987 applications, but when you look at the y-axis the number of applications exceeds 20,000. Instead of using shaded bars so that each bar height is equal to that year’s total number of applications, the number of admitted students and matriculants is added on to the total number of applications. This falsely inflates the height of the bars.

Which approach do you find communicates the information better, their single dual y-axes plot or the two separate plot approach? Why?

Solution

I think the two plot approach communicates this information better. The single plot would be fine if the y-axes were the same or could be directly mapped on to each other, but these axes are different which can make it difficult to discern which data is mapped onto which axis. Additionally, the frequency of number lables clutter the visualization and some labels overlap which impacts readability. In the visualization’s current state, it’s best to use two separate plots.

Hints:

  • Form 4 datasets (helps you get organized, but not entirely necessary):
    • 1 that has bar chart data,
    • 1 that has bar chart label data,
    • 1 that has line chart data, and
    • 1 that has line chart labels
  • Consider using ggsave() to save the image with a fixed size so it is easier to pick font sizes.
Solution
Code
# data wrangling
bar_data <- admin_data %>%
  select(-contains("_rate")) %>%
    pivot_longer(
      cols = -year,
      names_to = "category",
      values_to = "value"
    ) %>%
    mutate(
      bar_label = prettyNum(value, big.mark = ",")
    )

# barplot
barplot <- ggplot(data = bar_data, aes(x = year, y = value, fill = category)) +
  geom_col(
    position = "identity", 
    width = 0.8
    ) +
   geom_text(
     aes(label = bar_label),
     color = "white",
     size = 2,
     vjust = 1,
     nudge_y = -300
    ) +
  scale_x_continuous(
    name = "Entering Year",
    breaks = 1999:2020, 
    expand = c(0, 0.25)
  ) +
  scale_y_continuous(
    name = "Applications", 
    breaks = seq(0, 50000, 5000),
    expand = c(0, 0), 
    limits = c(0, 50000),
    labels = scales::label_comma()
  ) +
  scale_fill_manual(
    name = NULL,
    limits = c("matriculants", "admitted_students", "applications"),
    values = c("#4E2A84", "#836EAA", "#B6ACD1"),
    labels = c("Matriculants", "Admiited Students", "Applications"),
  ) +
  theme_classic() +
  theme(
    legend.justification = c(0.5,1),
    legend.position = c(0.5,1),
    legend.direction = "horizontal",
    plot.title = element_text(hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5)
  ) +
  labs(title = "Northwestern University",
       subtitle = "Undergraduate Admissions 1999-2000")
Code
# data wrangling
rate_data <- admin_data %>%
  select(year, contains("_rate")) %>%
    pivot_longer(
      cols = -year,
      names_to = "rate_type",
      values_to = "value"
    ) %>%
    mutate(
      rate_label = str_c(value, "%"),
      label_y = case_when(
        rate_type == "yield_rate" ~ value + 2,
        rate_type == "admission_rate" ~ value - 2
      )
    )

# rate plot
lineplot <- ggplot(data = rate_data, aes(x = year, y = value)) +
  geom_line(
    aes(color = rate_type)
    ) +
  geom_point(
    aes(color = rate_type, shape = rate_type)
  ) +
   geom_text(
     aes(y = label_y, 
         label = rate_label
         ),
     size = 2
    ) +
  scale_x_continuous(
    name = "Entering Year",
    breaks = 1999:2020, 
    expand = c(0, 0.3)
  ) +
  scale_y_continuous(
    name = "Rate", 
    expand = c(0, 0), 
    limits = c(0, 60),
    labels = scales::label_percent(scale = 1),
    position = "right"
  ) +
  scale_shape_manual(
    name = NULL, 
    labels = c("Admission Rate", "Yield Rate"),
    values = c(15, 8)
  ) +
  scale_color_discrete(
    name = NULL, 
    labels = c("Admission Rate", "Yield Rate")
  ) +
  theme_classic() +
  theme(
    legend.justification = c(0.5,1),
    legend.position = c(0.5,1),
    legend.direction = "horizontal"
  )
Code
#final plot
combined_plot <- barplot / lineplot

combined_plot